package shujia.day19.lambdademo4;
/*
    函数式编程

    能写成lambda表达式的前提：
        1、要有一个接口【作为方法参数类型，返回值类型】
        2、这个接口必须有且仅有一个抽象方法

    需求：
        1、过滤出年龄大于19岁的员工
        2、过滤出工资大于10000的员工

    实现1的缺点：
        当我的过滤需求越来越多的时候，我们需要写更多的过滤方法，而这些方法我们发现也就是在判断的时候不一样。
        能否只写一个方法，完成不同的过滤需求呢？
        答：可以，搞一个接口，这个中写个抽象方法，针对不同的过滤需求，对这个抽象方法做不同的实现

    实现2的缺点：
        虽然我们利用一个接口，实现了一个方法做不同的过滤，但是当我的过滤需求越来越多的时候，我们需要写更多的实现类

    实现3:使用匿名内部类传参，代替实现2的自己造一个实现类
 */


import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class LambdaDemo1 {
    private static List<Staff> staffList = Arrays.asList(
            new Staff(1001,"张成阳1",20,12000),
            new Staff(1002,"张成阳2",16,15000),
            new Staff(1003,"张成阳3",18,7000),
            new Staff(1004,"张成阳4",19,14000),
            new Staff(1005,"张成阳5",22,7000)
    );


    public static void main(String[] args) {
        System.out.println("================过滤出年龄大于19岁的员工==================");
        List<Staff> staffListRes1 = filterStaffWithCon(staffList, new FilterStaff() {
            @Override
            public boolean filterStaffWithCondition(Staff staff) {
                return staff.getAge()>19;
            }
        });
        for (Staff staff : staffListRes1) {
            System.out.println(staff);
        }

        System.out.println("================过滤出工资大于10000的员工==================");
        List<Staff> staffListRes2 = filterStaffWithCon(staffList, new FilterStaff() {
            @Override
            public boolean filterStaffWithCondition(Staff staff) {
                return staff.getSalary()>10000;
            }
        });
        for (Staff staff : staffListRes2) {
            System.out.println(staff);
        }

        System.out.println("================过滤出工资大于10000的员工==================");
        List<Staff> staffListRes3 = filterStaffWithCon(staffList, new FilterStaff() {
            @Override
            public boolean filterStaffWithCondition(Staff staff) {
                return staff.getName().startsWith("张");
            }
        });
        for (Staff staff : staffListRes3) {
            System.out.println(staff);
        }
    }

    /*
        写一个接口，接口中有一个判断员工的功能，将接口作为方法的第二个参数传入
        将来调用该方法的时候，需要传入一个实现该接口的实现类对象，就明确了如何判断员工的代码逻辑

     */
    public static List<Staff> filterStaffWithCon(List<Staff> staffList, FilterStaff filterStaff){
        ArrayList<Staff> list1 = new ArrayList<>();
        for (Staff staff : staffList) {
            if(filterStaff.filterStaffWithCondition(staff)){
                list1.add(staff);
            }
        }

        return list1;
    }

}
